#include <iostream>
#include <thread>
#include <vector>
#include <mutex>
#include <chrono>
#include <random>

std::mutex mtx;
std::vector<bool> sent(10, false), acked(10, false); // 窗口大小为10
int currentSeq = 0; // 当前序列号

void sendPackets() {
    static std::default_random_engine generator(std::random_device{}());
    std::uniform_int_distribution<int> dist(1, 100);
    
    while(true) {
        std::unique_lock<std::mutex> lock(mtx);
        for(int i = 0; i < 10; ++i) {
            if(!sent[i] && !acked[i]) { // 允许发送但尚未发送
                bool lost = dist(generator) <= 20; // 20%丢包率
                if (!lost) sent[i] = true;
                std::cout << "Send Packet " << (currentSeq + i) << (lost ? " Lost.\n" : ".\n");
            }
        }
        lock.unlock();
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }
}

void receiveAcks() {
    while(true) {
        std::unique_lock<std::mutex> lock(mtx);
        for(int i = 0; i < 10; ++i) {
            if(sent[i] && !acked[i]) { // 已发送但未收到确认
                acked[i] = true; // 模拟接收到确认
                std::cout << "Ack Packet " << (currentSeq + i) << ".\n";
            }
        }
        lock.unlock();
        std::this_thread::sleep_for(std::chrono::milliseconds(1500));
    }
}

void monitor() {
    while(true) {
        std::unique_lock<std::mutex> lock(mtx);
        int sentUnAcked = 0, canSend = 0, notAllowedSend = 0, allowedRecv = 0, notAllowedRecv = 0;
        for(int i = 0; i < 10; ++i) {
            if(sent[i] && !acked[i]) ++sentUnAcked; // 已发送但未收到确认
            if(!sent[i] && !acked[i]) ++canSend; // 允许发送但尚未发送
            if(acked[i]) ++allowedRecv; // 已发送确认并交付主机
            if(i >= currentSeq + 10) ++notAllowedRecv; // 不允许接收
        }
        notAllowedSend = 10 - (sentUnAcked + canSend); // 不允许发送
        
        std::cout << "Sent & Acked: " << allowedRecv 
                  << ", Sent UnAcked: " << sentUnAcked 
                  << ", Can Send: " << canSend 
                  << ", Not Allowed Send: " << notAllowedSend << "\n";
        
        lock.unlock();
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

int main() {
    std::thread t1(sendPackets);
    std::thread t2(receiveAcks);
    std::thread t3(monitor);

    t1.join();
    t2.join();
    t3.join();

    return 0;
}